package com.decent.ejfadmin.product.service.impl;

import cn.decent.component.shiro.service.AdminService;
import cn.decent.component.shiro.vo.AdminVO;
import com.decent.ejfadmin.common.bean.*;
import com.decent.ejfadmin.common.enums.ErrorCode;
import com.decent.ejfadmin.common.exception.SupException;
import com.decent.ejfadmin.common.util.Constants;
import com.decent.ejfadmin.common.util.DingTalkMessagePush;
import com.decent.ejfadmin.config.PlatUrlConfig;
import com.decent.ejfadmin.equity.cardproduct.dao.CardProductDao;
import com.decent.ejfadmin.product.dao.ProductDao;
import com.decent.ejfadmin.product.dao.SupUserDao;
import com.decent.ejfadmin.product.request.*;
import com.decent.ejfadmin.product.service.ProductService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author zhangchao
 * @date 2018/7/25 9:08
 */
@Slf4j
@Service
public class ProductServiceImpl implements ProductService {

    @Autowired
    private ProductDao productDao;

    @Autowired
    private SupUserDao supUserDao;

    @Autowired
    private AdminService adminService;
    @Autowired
    private DingTalkMessagePush dingTalkMessagePush;
    @Autowired
    private PlatUrlConfig platUrlConfig;

    /**
     * 查询产品列表
     *
     * @param param
     * @return
     */
    @Override
    public Page findProductListPage(ProductQueryParam param) {
        int total = productDao.queryProductCount(param);
        param.getPageUnit().setTotal(total);
        if (total == 0) {
            param.getPageUnit().setResultList(new ArrayList<>());
        } else {
            param.getPageUnit().setResultList(productDao.queryProductPage(param));
        }
        return param.getPageUnit();
    }

    /**
     * 修改产品上下架
     *
     * @param productIds
     * @param status
     * @param remark
     * @throws SupException
     */
    @Override
    public void changeProductStatus(String productIds, Integer status, String remark) throws SupException {
        boolean flag = (StringUtils.isBlank(productIds) || null == status || (status != 1 && status != 0 && status != 2));
        if (flag) {
            throw new SupException(ErrorCode.PARAM_ERROR, "参数有误");
        }
        AdminVO adminVO;
        try {
            adminVO = adminService.getCurrentAdmin();
        } catch (Exception e) {
            log.warn("ProductServiceImpl changeProductStatus adminService.getCurrentAdmin() occurs error");
            throw new SupException(ErrorCode.LOGIN_TIMEOUT, "getCurrentAdmin occurs error");
        }
        //查询其中权益产品
        List<String> productNames = productDao.querySupplyProducts(productIds);
        List<Long> productList = Arrays.asList(productIds.split(",")).stream().map(s -> Long.parseLong(s.trim())).collect(Collectors.toList());
        productDao.changeProductStatus(productList, status, remark);
        if (productNames != null && !productNames.isEmpty()) {
            String productNameStr = StringUtils.join(productNames, "、");
            dingTalkPush(productNameStr, status, adminVO.getName());
        }
    }

    /**
     * 产品上下架通知
     *
     * @param productNameStr 产品字符串
     * @return 返回
     */
    private void dingTalkPush(String productNameStr, Integer status, String admin) {
        StringBuffer contest = new StringBuffer();
        contest.append("豆乐卡平台权益产品:\n").append(productNameStr).append(status == 0 ? "下架" : "上架").append("\n操作人:").append(admin);
        //钉钉推送
        dingTalkMessagePush.dingDingRobotPushing(contest.toString(), platUrlConfig.getProductChangeInform());
    }

    /**
     * 获取会员模板密价
     *
     * @param param
     * @return
     */
    @Override
    public Page findModelPricePage(ModelPriceParam param) {
        int total = productDao.queryModelPriceCount(param);
        param.getPageUnit().setTotal(total);
        if (total == 0) {
            param.getPageUnit().setResultList(new ArrayList<>());
        } else {
            param.getPageUnit().setResultList(productDao.queryModelPricePage(param));
        }
        return param.getPageUnit();
    }


    /**
     * 获取会员密价
     *
     * @param param
     * @return
     */
    @Override
    public Page findUserPricePage(UserPriceParam param) {
        int total = productDao.queryUserPriceCount(param);
        param.getPageUnit().setTotal(total);
        if (total == 0) {
            param.getPageUnit().setResultList(new ArrayList<>());
        } else {
            param.getPageUnit().setResultList(productDao.queryUserPricePage(param));
        }
        return param.getPageUnit();
    }

    /**
     * 设置会员密价
     *
     * @param param
     * @return
     */
    @Override
    public void setUpUserPrice(SetUpUserPriceParam param) throws SupException {
        if (null == param || param.checkParams()) {
            throw new SupException(ErrorCode.PARAM_ERROR, "参数有误 " + param);
        }
        Integer deleteType = 4;
        List<String> userAccount = supUserDao.getUserAccount(param.getUserIds());
        AdminVO adminVO;
        try {
            adminVO = adminService.getCurrentAdmin();
        } catch (Exception e) {
            log.warn("ProductServiceImpl setUpUserPrice adminService.getCurrentAdmin() occurs error");
            throw new SupException(ErrorCode.LOGIN_TIMEOUT, "getCurrentAdmin occurs error");
        }
        if (null == adminVO) {
            throw new SupException(ErrorCode.LOGIN_TIMEOUT, "请重新登录后再操作");
        }
        param.setAdmin(adminVO.getName());
        param.exchangeParams();
        List<Long> productIdList = productDao.queryProductIdList(param.getFaceList(), param.getProductTypeList(), param.getAreaList());
        if (productIdList == null || productIdList.size() == 0) {
            throw new SupException(ErrorCode.PARAM_ERROR, "没有找到对应的产品");
        }
        param.setProductIdList(productIdList);
        switch (param.getMethod()) {
            case Constants.METHOD_UPDATE: {
                productDao.updateUserPrice(param);
                break;
            }
            case Constants.METHOD_ADD: {
                List<UserProductPrice> userProductPriceList = new ArrayList<>();
                for (Long productId : productIdList) {
                    for (Long userId : param.getUserIdList()) {
                        UserProductPrice userProductPrice = new UserProductPrice();
                        userProductPrice.setAdmin(param.getAdmin());
                        userProductPrice.setMaxPrice(param.getMaxPrice());
                        userProductPrice.setMinPrice(param.getMinPrice());
                        userProductPrice.setXianyuPrice(param.getXianyuPrice());
                        userProductPrice.setProductId(productId);
                        userProductPrice.setUserId(userId);
                        userProductPriceList.add(userProductPrice);
                    }
                }
                productDao.addUserPrice(userProductPriceList);
                break;
            }
            case Constants.METHOD_UP:
            case Constants.METHOD_DOWN: {
                param.setState(param.getMethod() == Constants.METHOD_UP ? Constants.STATE_OPEN : Constants.STATE_CLOSE);
                productDao.updateUserPrice(param);
                break;
            }
            case Constants.METHOD_DELETE: {
                productDao.deleteUserPrice(param);
                break;
            }
            default:
        }
    }


    /**
     * 设置会员模板密价
     *
     * @param param 价格信息bea
     */
    @Override
    public void setUpModelPrice(SetUpModelPriceParam param) throws SupException {
        if (null == param || param.checkParams()) {
            throw new SupException(ErrorCode.PARAM_ERROR, "参数有误 " + param);
        }
        AdminVO adminVO;
        try {
            adminVO = adminService.getCurrentAdmin();
        } catch (Exception e) {
            log.warn("ProductServiceImpl setUpModelPrice adminService.getCurrentAdmin() occurs error");
            throw new SupException(ErrorCode.LOGIN_TIMEOUT, "getCurrentAdmin occurs error");
        }
        if (null == adminVO) {
            throw new SupException(ErrorCode.LOGIN_TIMEOUT, "请重新登录后再操作");
        }
        param.setAdmin(adminVO.getName());
        param.exchangeParams();
        List<Long> productIdList = productDao.queryProductIdList(param.getFaceList(), param.getProductTypeList(), param.getAreaList());
        if (productIdList == null || productIdList.size() == 0) {
            throw new SupException(ErrorCode.PARAM_ERROR, "没有找到对应的产品");
        }
        param.setProductIdList(productIdList);
        switch (param.getMethod()) {
            case Constants.METHOD_UPDATE: {
                productDao.updateModelPrice(param);
                break;
            }
            case Constants.METHOD_ADD: {
                List<SupplyModelPrice> supplyModelPriceList = new ArrayList<>();
                for (Long productId : productIdList) {
                    SupplyModelPrice supplyModelPrice = new SupplyModelPrice();
                    supplyModelPrice.setAdmin(param.getAdmin());
                    supplyModelPrice.setMaxPrice(param.getMaxPrice());
                    supplyModelPrice.setMinPrice(param.getMinPrice());
                    supplyModelPrice.setProductId(productId);
                    supplyModelPrice.setModelId(param.getModelId());
                    supplyModelPriceList.add(supplyModelPrice);
                }
                productDao.addModelPrice(supplyModelPriceList);
                break;
            }
            case Constants.METHOD_UP:
            case Constants.METHOD_DOWN: {
                param.setState(param.getMethod() == Constants.METHOD_UP ? Constants.STATE_OPEN : Constants.STATE_CLOSE);
                productDao.updateModelPrice(param);
                break;
            }
            case Constants.METHOD_DELETE: {
                productDao.deleteModelPrice(param);
                break;
            }
            default:
        }
    }

    /**
     * 设置会员推荐返利折扣
     *
     * @param param
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void setUpRebateDiscount(SetUpRebateDiscountParam param) throws SupException {
        if (null == param || param.checkParams()) {
            throw new SupException(ErrorCode.PARAM_ERROR, "参数有误 " + param);
        }
        SupUser supUser = new SupUser();
        supUser.setUserId(param.getUserId());
        supUser.setRecommendId(param.getRecommendId());

        SupRebateConfig supRebateConfig = new SupRebateConfig();
        supRebateConfig.setDiscount(param.getRebateDiscount());
        supRebateConfig.setUserId(param.getRecommendId());

        //更新推荐人
        supUserDao.updateSupUserRecommendId(supUser.getUserId(), supUser.getRecommendId());
        //插入折扣
        productDao.insertRebateConfig(supRebateConfig);

    }


    /**
     * 添加密价模板
     *
     * @param supplyModel
     * @return
     */
    @Override
    public void addPriceModel(SupplyModel supplyModel) throws SupException {
        AdminVO adminVO = null;
        try {
            adminVO = adminService.getCurrentAdmin();
        } catch (Exception e) {
            log.warn("ProductServiceImpl addPriceModel adminService.getCurrentAdmin() occurs error");
            throw new SupException(ErrorCode.LOGIN_TIMEOUT, "getCurrentAdmin occurs error");
        }
        if (null == adminVO) {
            throw new SupException(ErrorCode.LOGIN_TIMEOUT, "请重新登录后再操作");
        }
        supplyModel.setAdmin(adminVO.getName());
        productDao.insert(supplyModel);
    }

    /**
     * 修改密价模板
     *
     * @param supplyModel
     * @return
     */
    @Override
    public void modifyPriceModel(SupplyModel supplyModel) throws SupException {
        if (null == supplyModel || supplyModel.getId() == null) {
            throw new SupException(ErrorCode.PARAM_ERROR, "参数有误 " + supplyModel);
        }
        AdminVO adminVO = null;
        try {
            adminVO = adminService.getCurrentAdmin();
        } catch (Exception e) {
            log.warn("ProductServiceImpl modifyPriceModel adminService.getCurrentAdmin() occurs error");
            throw new SupException(ErrorCode.LOGIN_TIMEOUT, "getCurrentAdmin occurs error");
        }
        if (null == adminVO) {
            throw new SupException(ErrorCode.LOGIN_TIMEOUT, "请重新登录后再操作");
        }
        supplyModel.setAdmin(adminVO.getName());
        productDao.update(supplyModel);
    }

    /**
     * 获取所有会员模板密价
     *
     * @param param 是否查询超快销和慢销
     * @return
     */
    @Override
    public List findModelPrice(boolean param) {
        return productDao.queryAllModel(param);
    }

    /**
     * 快速修改产品状态
     *
     * @param param
     * @throws SupException
     */
    @Override
    public void setProductStatus(SetUpModelPriceParam param) throws SupException {
        if (null == param || StringUtils.isBlank(param.getAreas()) || StringUtils.isBlank(param.getFaces())
                || StringUtils.isBlank(param.getProductTypes())) {
            throw new SupException(ErrorCode.PARAM_ERROR, "参数有误 " + param);
        }
        AdminVO adminVO;
        try {
            adminVO = adminService.getCurrentAdmin();
        } catch (Exception e) {
            log.warn("ProductServiceImpl setProductStatus adminService.getCurrentAdmin() occurs error");
            throw new SupException(ErrorCode.LOGIN_TIMEOUT, "getCurrentAdmin occurs error");
        }
        if (null == adminVO) {
            throw new SupException(ErrorCode.LOGIN_TIMEOUT, "请重新登录后再操作");
        }
        param.setAdmin(adminVO.getName());
        param.exchangeParams();
        List<Long> productIdList = productDao.queryProductIdList(param.getFaceList(), param.getProductTypeList(), param.getAreaList());
        if (productIdList == null || productIdList.size() == 0) {
            throw new SupException(ErrorCode.PARAM_ERROR, "没有找到对应的产品");
        }
        param.setProductIdList(productIdList);
        productDao.updateProductStatus(param);
    }

    /**
     * 查询所有会员
     *
     * @param userAccount 会员编号
     * @return
     */
    @Override
    public List<SupUser> queryUserByAccount(String userAccount) {
        if (org.apache.commons.lang3.StringUtils.isBlank(userAccount)) {
            return Collections.EMPTY_LIST;
        }
        String mark = ",";
        userAccount = org.apache.commons.lang3.StringUtils.replace(userAccount, "，", mark);
        if (userAccount.endsWith(mark)) {
            return Collections.EMPTY_LIST;
        }
        return productDao.queryUserByAccount(userAccount);

    }

    /**
     * 新增产品
     *
     * @param product
     * @return
     */
    @Override
    public MessageBean addProduct(SupplyProduct product) throws Exception {
        //参数校验
        MessageBean msg = product.check();
        if (msg != null) {
            return msg;
        }
        SupplyProduct productList = productDao.queryProductByProductNo(product.getCardProductId());
        if (Objects.nonNull(productList)) {
            return MessageBean.fail(product.getCardProductId() + "产品编码已存在!");
        }
        //通过运营商查询对应的产品类型
        Integer type = productDao.queryTypeByProductType(product.getProductType());
        if (type == null) {
            return MessageBean.fail("该运营商对应的产品类型不存在!");
        }
        product.setAdmin(adminService.getCurrentAdmin().getName());
        int count = productDao.addProduct(product);
        if (count != 1) {
            return MessageBean.fail();
        }
        return MessageBean.success();
    }

    /**
     * 修改产品
     *
     * @param product
     * @return
     */
    @Override
    public MessageBean editProduct(SupplyProduct product) throws Exception {
        //参数校验
        MessageBean msg = product.check();
        if (msg != null) {
            return msg;
        }
        //通过运营商查询对应的产品类型
        Integer type = productDao.queryTypeByProductType(product.getProductType());
        if (type == null) {
            return MessageBean.fail("该运营商对应的产品类型不存在!");
        }
        product.setAdmin(adminService.getCurrentAdmin().getName());
        int count = productDao.editProduct(product);
        if (count != 1) {
            return MessageBean.fail();
        }
        return MessageBean.success();
    }

    /**
     * 编辑产品校验规则
     *
     * @param productIds   产品id
     * @param cardRestrict 校验规则
     * @return
     */
    @Override
    public MessageBean updateCardRestrict(String productIds, String cardRestrict) throws Exception {
        if (StringUtils.isBlank(productIds) || StringUtils.isBlank(cardRestrict)) {
            return MessageBean.fail("请选择产品或输入校验规则!");
        }

        List<Long> productList = Arrays.stream(productIds.split(",")).map(s -> Long.parseLong(s.trim())).collect(Collectors.toList());
        String name = adminService.getCurrentAdmin().getName();
        if (productDao.updateCardRestrict(productList, cardRestrict, name) < 1) {
            return MessageBean.fail("更新0条记录,操作失败!");
        }
        return MessageBean.success();
    }

    /**
     * 删除产品
     *
     * @param productIds 产品id
     * @return
     */
    @Override
    public MessageBean deleteProduct(String productIds) {
        int count = productDao.deleteProduct(productIds);
        if (count > 0) {
            return MessageBean.success("操作成功" + count + "条");
        }
        return MessageBean.fail();
    }

    /**
     * 克隆密价
     *
     * @param sourceUserAccount
     * @param targetUserAccount
     * @param productType
     * @return
     */
    @Override
    public MessageBean cloneUserPrice(String sourceUserAccount, String targetUserAccount, Integer productType) {
        //查找目标
        SupUser user = productDao.queryUserAccount(sourceUserAccount);
        if (Objects.isNull(user)) {
            return MessageBean.fail("未找到源目标");
        }
        targetUserAccount = targetUserAccount.replace("，", ",");
        String[] targetUserAccountArr = targetUserAccount.split(",");
        List<Long> userIds = new ArrayList<>();
        for (String targetUserAccountArray : targetUserAccountArr) {
            SupUser supUser = productDao.queryUserAccount(targetUserAccountArray);
            if (Objects.isNull(supUser)) {
                return MessageBean.fail("克隆失败：" + targetUserAccountArray + "目标会员账号不存在");
            }
            userIds.add(supUser.getUserId());
        }
        try {
            int i = cloneUserPriceStart(user.getUserId(), userIds, productType);
            MessageBean mb = new MessageBean();
            mb.setMessage("克隆" + i + "条密价");
            mb.setSuccess(true);
            return mb;
        } catch (Exception e) {
            log.warn("克隆会员密价异常: ", e);
            String duplicateEntry = "Duplicate entry";
            if (e.getLocalizedMessage().contains(duplicateEntry)) {
                return MessageBean.fail("密价重复");
            }
            return MessageBean.fail(e.getMessage());
        }
    }

    /**
     * 密价克隆
     *
     * @param forId
     * @param targetId
     * @param productType
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public int cloneUserPriceStart(Long forId, List<Long> targetId, Integer productType) throws Exception {
        AdminVO adminVO = adminService.getCurrentAdmin();
        int i = 0;
        for (Long id : targetId) {
            List<Long> productIds = productDao.getClearProductId(forId, productType);
            if (Objects.isNull(productIds) || productIds.size() < 1) {
                continue;
            }
            productDao.clearPriceByUserId(id, StringUtils.join(productIds.toArray(), ","));
            for (Long productId : productIds) {
                i += productDao.cloneUserPrice(forId, id, productId, adminVO.getName());
            }
        }
        return i;
    }

    /**
     * 设置会员密价
     *
     * @param ids
     * @param status
     * @return
     */
    @Override
    public MessageBean setCecretPriceStatus(Long[] ids, Integer status) throws Exception {
        AdminVO adminVO = adminService.getCurrentAdmin();
        String statusChange = Integer.valueOf(1).equals(status) ? "上架" : "下架";
        int num = productDao.updateCecretPriceStatus(StringUtils.join(ids, ","), status, adminVO.getName() + " 操作" + statusChange);
        return MessageBean.success("更新成功" + num + "条");
    }
}
